/**
 * 表单通用逻辑组合式函数
 */
import { ref, reactive, toRaw } from 'vue'
import { ElMessage } from 'element-plus'
import type { FormInstance } from 'element-plus'

/**
 * 表单Hook
 * @param initialForm 表单初始值
 */
export function useForm<T extends Record<string, any>>(
  initialForm: T
) {
  // 表单引用
  const formRef = ref<FormInstance>()

  // 表单数据
  const formData = reactive<T>({ ...initialForm })

  // 加载状态
  const loading = ref(false)

  /**
   * 验证表单
   */
  const validate = async (): Promise<boolean> => {
    if (!formRef.value) return false

    try {
      await formRef.value.validate()
      return true
    } catch (error) {
      console.error('validate error:', error)
      return false
    }
  }

  /**
   * 验证字段
   */
  const validateField = async (prop: string): Promise<boolean> => {
    if (!formRef.value) return false

    try {
      await formRef.value.validateField(prop)
      return true
    } catch (error) {
      console.error('validateField error:', error)
      return false
    }
  }

  /**
   * 重置表单
   */
  const resetForm = () => {
    formRef.value?.resetFields()
  }

  /**
   * 清空验证
   */
  const clearValidate = () => {
    formRef.value?.clearValidate()
  }

  /**
   * 提交表单
   * @param submitApi 提交API函数
   * @param successMsg 成功提示消息
   */
  const submitForm = async (
    submitApi: (data: T) => Promise<any>,
    successMsg: string = '操作成功'
  ): Promise<boolean> => {
    // 验证表单
    const valid = await validate()
    if (!valid) return false

    try {
      loading.value = true
      await submitApi(toRaw(formData) as T)
      ElMessage.success(successMsg)
      return true
    } catch (error) {
      console.error('submitForm error:', error)
      return false
    } finally {
      loading.value = false
    }
  }

  /**
   * 设置表单数据
   */
  const setFormData = (data: Partial<T>) => {
    Object.assign(formData, data)
  }

  /**
   * 获取表单数据
   */
  const getFormData = (): T => {
    return { ...toRaw(formData) } as T
  }

  return {
    formRef,
    formData,
    loading,
    validate,
    validateField,
    resetForm,
    clearValidate,
    submitForm,
    setFormData,
    getFormData
  }
}
